﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing;
using System.Windows.Forms;

using Layers;
using HoldemGame;
using ZedGraph;


namespace HoldemView
{
    public class ZedChartAdapter : IPointList
    {
        private IChartData<XY> _data;
        private ChartForm _form;
        private Timer _timer;
        private List<StockPt> _cache = new List<StockPt>();

        public ZedChartAdapter(IChartData<XY> data, ChartForm form)
        {
            _form = form;
            _data = data;
            _data.Changed += new NotifyCollectionChangedEventHandler(Data_Changed);
            Update(0, _data.Count-1);
        }

        void Update(int start, int end)
        {
            if (end < start)
                return;

            StockPt curr = new StockPt();
            curr.X = _data[start].X;
            curr.Open = curr.Close = curr.High = curr.Low = _data[start].Y;

            int maxNumPoints = 3000;

            int K = (end-start+1) / maxNumPoints;
            if (K == 0)
                K = 1;
            
            _cache.Add(curr);
            for (int i = start+1; i <= end; i++)
            {
                curr.High = Math.Max(curr.High, _data[i].Y);
                curr.Low = Math.Min(curr.Low, _data[i].Y);
                curr.Close = _data[i].Y;
                if (i % K == 0)
                {
                    curr = new StockPt();
                    curr.X = _data[i].X;
                    curr.Open = curr.Close = curr.High = curr.Low = _data[i].Y;
                }
            }
            _form.ChartDirty = true;
        }

        void Data_Changed(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                Update(e.NewStartingIndex, _data.Count - 1);
            }
            else if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                _cache.Clear();
                Update(0, _data.Count);
            }
            _form.ChartDirty = true;
        }

        #region IPointList Members

        public PointPair this[int index]
        {
            get { return _cache[index]; }
        }

        public int Count
        {
            get { return _cache.Count; }
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class ZedChartManager
    {
        private Dictionary<string, ChartForm> _charts = new Dictionary<string, ChartForm>();
        private Dictionary<IChartData, ZedChartAdapter> _adapters = new Dictionary<IChartData, ZedChartAdapter>();

        private static ZedChartManager _Instance;

        public static ZedChartManager Instance
        {
            get { if (null == _Instance) new ZedChartManager(); return _Instance; }
        }

        public ZedChartManager()
        {
            _Instance = this;
        }

        private ChartForm NewChart(string chartId)
        {
            ChartForm cf = new ChartForm();
            _charts.Add(chartId, cf);
            return cf;

        }

        public ChartForm this[string chartId]
        {
            get
            {
                ChartForm chart = null;
                _charts.TryGetValue(chartId, out chart);
                return chart;
            }
        }
        private static Color GetColor(IChartData data, int count)
        {
            Color[] colors = new Color[]{
                Color.Red, Color.Green, Color.Blue, Color.DarkGray, Color.Magenta, Color.Pink};
            return Color.FromArgb(255-count * 128/ colors.Length, colors[count % colors.Length]);
        }

        public ZedChartAdapter Show(string chartId, IChartData data)
        {
            ChartForm chart = this[chartId];
            if (null == chart)
                chart = NewChart(chartId);
            ZedChartAdapter series = new ZedChartAdapter(data as IChartData<XY>, chart);
            chart.Chart.MasterPane.PaneList[0].AddCurve(
                data.ID, series, GetColor(data, chart.Chart.MasterPane.PaneList[0].CurveList.Count), SymbolType.None);
            _adapters.Add(data, series);
            chart.Text = chartId;
            if (!chart.Visible)
            {
                chart.Show();
                chart.Visible = true;
            }

            return series;
        }
    }
}